1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.io;
18  
19  import com.google.common.annotations.Beta;
20  import com.google.common.annotations.VisibleForTesting;
21  
22  import java.io.Closeable;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.Reader;
26  import java.util.logging.Level;
27  import java.util.logging.Logger;
28  
29  import javax.annotation.Nullable;
30  
31  /**
32   * Utility methods for working with {@link Closeable} objects.
33   *
34   * @author Michael Lancaster
35   * @since 1.0
36   */
37  @Beta
38  public final class Closeables {
39    @VisibleForTesting static final Logger logger
40        = Logger.getLogger(Closeables.class.getName());
41  
42    private Closeables() {}
43  
44    /**
45     * Closes a {@link Closeable}, with control over whether an {@code IOException} may be thrown.
46     * This is primarily useful in a finally block, where a thrown exception needs to be logged but
47     * not propagated (otherwise the original exception will be lost).
48     *
49     * <p>If {@code swallowIOException} is true then we never throw {@code IOException} but merely log
50     * it.
51     *
52     * <p>Example: <pre>   {@code
53     *
54     *   public void useStreamNicely() throws IOException {
55     *     SomeStream stream = new SomeStream("foo");
56     *     boolean threw = true;
57     *     try {
58     *       // ... code which does something with the stream ...
59     *       threw = false;
60     *     } finally {
61     *       // If an exception occurs, rethrow it only if threw==false:
62     *       Closeables.close(stream, threw);
63     *     }
64     *   }}</pre>
65     *
66     * @param closeable the {@code Closeable} object to be closed, or null, in which case this method
67     *     does nothing
68     * @param swallowIOException if true, don't propagate IO exceptions thrown by the {@code close}
69     *     methods
70     * @throws IOException if {@code swallowIOException} is false and {@code close} throws an
71     *     {@code IOException}.
72     */
73    public static void close(@Nullable Closeable closeable,
74        boolean swallowIOException) throws IOException {
75      if (closeable == null) {
76        return;
77      }
78      try {
79        closeable.close();
80      } catch (IOException e) {
81        if (swallowIOException) {
82          logger.log(Level.WARNING,
83              "IOException thrown while closing Closeable.", e);
84        } else {
85          throw e;
86        }
87      }
88    }
89  
90    /**
91     * Closes the given {@link InputStream}, logging any {@code IOException} that's thrown rather
92     * than propagating it.
93     *
94     * <p>While it's not safe in the general case to ignore exceptions that are thrown when closing
95     * an I/O resource, it should generally be safe in the case of a resource that's being used only
96     * for reading, such as an {@code InputStream}. Unlike with writable resources, there's no
97     * chance that a failure that occurs when closing the stream indicates a meaningful problem such
98     * as a failure to flush all bytes to the underlying resource.
99     *
100    * @param inputStream the input stream to be closed, or {@code null} in which case this method
101    *     does nothing
102    * @since 17.0
103    */
104   public static void closeQuietly(@Nullable InputStream inputStream) {
105     try {
106       close(inputStream, true);
107     } catch (IOException impossible) {
108       throw new AssertionError(impossible);
109     }
110   }
111 
112   /**
113    * Closes the given {@link Reader}, logging any {@code IOException} that's thrown rather than
114    * propagating it.
115    *
116    * <p>While it's not safe in the general case to ignore exceptions that are thrown when closing
117    * an I/O resource, it should generally be safe in the case of a resource that's being used only
118    * for reading, such as a {@code Reader}. Unlike with writable resources, there's no chance that
119    * a failure that occurs when closing the reader indicates a meaningful problem such as a failure
120    * to flush all bytes to the underlying resource.
121    *
122    * @param reader the reader to be closed, or {@code null} in which case this method does nothing
123    * @since 17.0
124    */
125   public static void closeQuietly(@Nullable Reader reader) {
126     try {
127       close(reader, true);
128     } catch (IOException impossible) {
129       throw new AssertionError(impossible);
130     }
131   }
132 }